﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Geometry;
using System.Diagnostics;

namespace TestGeometry {
    public class TestBBox {
        public void run() {
            testUnion();
            testOverlap();
            testInside();
            testTransform();
        }

        public void testUnion() {
            BBox b = new BBox(Point.ORIGIN);
            Point ppos = new Point(1, 2, 3);
            Point pneg = new Point(-1, -2, -3);

            BBox bu = BBox.union(b, ppos);
            Util.assertZero(bu.pMin.x);
            Util.assertZero(bu.pMin.y);
            Util.assertZero(bu.pMin.z);
            Util.assertEquals(bu.pMax.x, ppos.x);
            Util.assertEquals(bu.pMax.y, ppos.y);
            Util.assertEquals(bu.pMax.z, ppos.z);

            bu = BBox.union(bu, pneg);
            Util.assertEquals(bu.pMin.x, pneg.x);
            Util.assertEquals(bu.pMin.y, pneg.y);
            Util.assertEquals(bu.pMin.z, pneg.z);
        }

        public void testOverlap() {
            float bias = 10.0f;
            BBox b = new BBox(new Point(-bias, -bias, -bias), new Point(bias, bias, bias));
            Point p2 = new Point(2 * bias, 2 * bias, 2 * bias);
            Debug.Assert(b.overlaps(new BBox(Point.ORIGIN)));
            Debug.Assert(b.overlaps(new BBox(Point.ORIGIN, p2)));
            Debug.Assert(!b.overlaps(new BBox(new Point(p2))));
        }

        public void testInside() {
            float bias = 10.0f;
            Point p = new Point(bias, bias, bias);
            BBox b = new BBox(-p, p);
            Debug.Assert(b.inside(p / 2));
            Debug.Assert(!b.inside(p * 2));
        }

        public void testTransform() {
            float bias = 100.0f;
            Point p = new Point(bias, bias, bias);
            BBox b = new BBox(-p, p);
            float PI4 = 45.0f;
            
            Transform tx = Transform.rotateX(PI4);
            Transform ty = Transform.rotateY(PI4);
            Transform tz = Transform.rotateZ(PI4);

            float diag = (float)Math.Sqrt(bias * bias + bias * bias);
            BBox tbx = tx * b;
            Util.assertEquals(tbx.pMax.x, bias);
            Util.assertEquals(tbx.pMin.x, -bias);
            Util.assertEquals(tbx.pMax.y, diag);
            Util.assertEquals(tbx.pMin.y, -diag);
            Util.assertEquals(tbx.pMax.z, diag);
            Util.assertEquals(tbx.pMin.z, -diag);

            BBox tby = ty * b;
            Util.assertEquals(tby.pMax.x, diag);
            Util.assertEquals(tby.pMin.x, -diag);
            Util.assertEquals(tby.pMax.y, bias);
            Util.assertEquals(tby.pMin.y, -bias);
            Util.assertEquals(tby.pMax.z, diag);
            Util.assertEquals(tby.pMin.z, -diag);

            BBox tbz = tz * b;
            Util.assertEquals(tbz.pMax.x, diag);
            Util.assertEquals(tbz.pMin.x, -diag);
            Util.assertEquals(tbz.pMax.y, diag);
            Util.assertEquals(tbz.pMin.y, -diag);
            Util.assertEquals(tbz.pMax.z, bias);
            Util.assertEquals(tbz.pMin.z, -bias);
        }
    }
}
